﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace BaseTool
{
    /// <summary>
    /// 截图控制类
    /// </summary>
    public static class ScreenControl
    {
        /// <summary> 全屏左上角 + 大小 </summary>
        private static int[] FullSize = new int[4] { 0, 0, 0, 0 };
        /// <summary> 窗口左上角 + 大小 </summary>
        private static int[] FormSize = new int[4] { 0, 0, 0, 0 };

        #region 获取系统DPI缩放倍数
        /// <summary>
        /// 获取DC句柄
        /// </summary>
        /// <param name="ptr"> DC句柄 </param>
        /// <returns></returns>
        [DllImport("user32.dll")]
        private static extern IntPtr GetDC(IntPtr ptr);
        /// <summary>
        /// 获取设备特定信息
        /// </summary>
        /// <param name="hdc"> DC句柄 </param>
        /// <param name="nIndex"> 指针 </param>
        /// <returns></returns>
        [DllImport("gdi32.dll")]
        private static extern int GetDeviceCaps(IntPtr hdc, int nIndex);
        /// <summary>
        /// 释放DC句柄
        /// </summary>
        /// <param name="hWnd"> 初始化为零的指针 </param>
        /// <param name="hDc"> DC句柄 </param>
        /// <returns></returns>
        [DllImport("user32.dll", EntryPoint = "ReleaseDC")]
        private static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDc);

        /// <summary> 显示宽度（用像素表示） </summary>
        private const int HORZRES = 8;
        /// <summary> 显示高度（用像素表示） </summary>
        private const int VERTRES = 10;
        /// <summary> 沿显示宽度方向，每一逻辑单位的像素数 </summary>
        private const int LOGPIXELSX = 88;
        /// <summary> 沿显示高度方向，每一逻辑单位的像素数 </summary>
        private const int LOGPIXELSY = 90;
        /// <summary>  </summary>
        private const int DESKTOPVERTRES = 117;
        /// <summary>  </summary>
        private const int DESKTOPHORZRES = 118;

        /// <summary>
        /// 获取屏幕分辨率当前物理大小
        /// </summary>
        public static Size WorkingArea
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                Size size = new Size();
                size.Width = GetDeviceCaps(hdc, HORZRES);
                size.Height = GetDeviceCaps(hdc, VERTRES);
                ReleaseDC(IntPtr.Zero, hdc);
                return size;
            }
        }
        /// <summary>
        /// 当前系统DPI_X 大小 一般为96
        /// </summary>
        public static int DpiX
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                int DpiX = GetDeviceCaps(hdc, LOGPIXELSX);
                ReleaseDC(IntPtr.Zero, hdc);
                return DpiX;
            }
        }
        /// <summary>
        /// 当前系统DPI_Y 大小 一般为96
        /// </summary>
        public static int DpiY
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                int DpiX = GetDeviceCaps(hdc, LOGPIXELSY);
                ReleaseDC(IntPtr.Zero, hdc);
                return DpiX;
            }
        }

        /// <summary>
        /// 获取宽度缩放百分比
        /// </summary>
        public static float ScaleX
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                float ScaleX = (float)GetDeviceCaps(hdc, DESKTOPHORZRES) / (float)GetDeviceCaps(hdc, HORZRES);
                ReleaseDC(IntPtr.Zero, hdc);
                return ScaleX;
            }
        }
        /// <summary>
        /// 获取高度缩放百分比
        /// </summary>
        public static float ScaleY
        {
            get
            {
                IntPtr hdc = GetDC(IntPtr.Zero);
                float ScaleY = (float)(float)GetDeviceCaps(hdc, DESKTOPVERTRES) / (float)GetDeviceCaps(hdc, VERTRES);
                ReleaseDC(IntPtr.Zero, hdc);
                return ScaleY;
            }
        }
        #endregion

        /// <summary>
        /// 设置全屏大小
        /// </summary>
        /// <param name="BW"></param>
        /// <param name="BH"></param>
        public static void SetFullScreenSize(int BW, int BH)
        {
            FullSize = new int[4] { 0, 0, BW, BH };
        }

        /// <summary>
        /// 设置软件截图大小
        /// </summary>
        /// <param name="LX"></param>
        /// <param name="LY"></param>
        /// <param name="SW"></param>
        /// <param name="SH"></param>
        public static void SetFormScreenSize(int LX, int LY, int SW, int SH)
        {
            FormSize = new int[4] { LX, LY, SW, SH };
        }

        /// <summary> 全屏截图 </summary>
        public static string ScreenFull()
        {
            return ScreenShot(FullSize[0], FullSize[1], FullSize[2], FullSize[3], "全屏截图");
        }
        /// <summary> 软件截图 </summary>
        public static string ScreenForm()
        {
            return ScreenShot(FormSize[0], FormSize[1], FormSize[2], FormSize[3], "软件截图");
        }
        /// <summary> 自定义截图 </summary>
        public static string ScreenForm(int LX, int LY, int SW, int SH)
        {
            return ScreenShot(LX, LY, SW, SH, "自定义截图");
        }

        /// <summary>
        /// 截图
        /// </summary>
        public static string ScreenShot(int LX, int LY, int SW, int SH, string msg)
        {
            try
            {
                if (SW == 0 || SH == 0)
                    return $"{msg}失败：尺寸为零";

                double scaleX = ScaleX;
                double scaleY = ScaleY;

                Bitmap bit = new Bitmap((int)(SW * scaleX), (int)(SH * scaleY));//截取的大小
                Graphics g = Graphics.FromImage(bit);
                g.CopyFromScreen(new Point((int)(LX * scaleX), (int)(LY * scaleY)), new Point(0, 0), bit.Size);

                DateTime now = DateTime.Now;
                string SavePath = $"{PathTool.DataScreenImagePath}{now.ToString("yyyy年MM月dd日")}\\";
                string FileName = $"Screen_{now.ToString("HHmmss_fff")}.bmp";
                if (!Directory.Exists(SavePath))
                    Directory.CreateDirectory(SavePath);
                bit.Save(SavePath + FileName);
                return $"{msg}成功：保存路径{SavePath}{FileName}";
            }
            catch (Exception ex)
            {
                Log.SaveError(ex);
                return $"{msg}异常：{ex.Message}";
            }
        }
    }
}
